///////*
////// * Copyright 2011 ZXing authors
////// *
////// * Licensed under the Apache License, Version 2.0 (the "License");
////// * you may not use this file except in compliance with the License.
////// * You may obtain a copy of the License at
////// *
////// *      http://www.apache.org/licenses/LICENSE-2.0
////// *
////// * Unless required by applicable law or agreed to in writing, software
////// * distributed under the License is distributed on an "AS IS" BASIS,
////// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
////// * See the License for the specific language governing permissions and
////// * limitations under the License.
////// */
//////
//////package com.google.zxing.maxicode.decoder;
//////
//////import com.google.zxing.ChecksumException;
//////import com.google.zxing.DecodeHintType;
//////import com.google.zxing.FormatException;
//////import com.google.zxing.common.BitMatrix;
//////import com.google.zxing.common.DecoderResult;
//////import com.google.zxing.common.reedsolomon.GenericGF;
//////import com.google.zxing.common.reedsolomon.ReedSolomonDecoder;
//////import com.google.zxing.common.reedsolomon.ReedSolomonException;
//////import java.util.Hashtable;
//////
//////
///////**
////// * <p>The main class which implements MaxiCode decoding -- as opposed to locating and extracting
////// * the MaxiCode from an image.</p>
////// *
////// * @author Manuel Kasten
////// */
//////public final class Decoder {
//////
//////  private static final int ALL = 0;
//////  private static final int EVEN = 1;
//////  private static final int ODD = 2;
//////
//////  private final ReedSolomonDecoder rsDecoder;
//////
//////  public Decoder() {
//////    rsDecoder = new ReedSolomonDecoder(GenericGF.MAXICODE_FIELD_64);
//////  }
//////
//////  public DecoderResult decode(BitMatrix bits) throws ChecksumException, FormatException {
//////    return decode(bits, null);
//////  }
//////
//////  public DecoderResult decode(BitMatrix bits,
//////                              //Map<DecodeHintType,?> hints) throws FormatException, ChecksumException {
//////          Hashtable hints) throws FormatException, ChecksumException {
//////    BitMatrixParser parser = new BitMatrixParser(bits);
//////    byte[] codewords = parser.readCodewords();
//////
//////    correctErrors(codewords, 0, 10, 10, ALL);
//////    int mode = codewords[0] & 0x0F;
//////    byte[] datawords;
//////    switch (mode) {
//////      case 2:
//////      case 3:
//////      case 4:
//////        correctErrors(codewords, 20, 84, 40, EVEN);
//////        correctErrors(codewords, 20, 84, 40, ODD);
//////        datawords = new byte[94];
//////        break;
//////      case 5:
//////        correctErrors(codewords, 20, 68, 56, EVEN);
//////        correctErrors(codewords, 20, 68, 56, ODD);
//////        datawords = new byte[78];
//////        break;
//////      default:
//////        throw FormatException.getFormatInstance();
//////    }
//////
//////    System.arraycopy(codewords, 0, datawords, 0, 10);
//////    System.arraycopy(codewords, 20, datawords, 10, datawords.length - 10);
//////
//////    return DecodedBitStreamParser.decode(datawords, mode);
//////  }
//////
//////  private void correctErrors(byte[] codewordBytes,
//////                             int start,
//////                             int dataCodewords,
//////                             int ecCodewords,
//////                             int mode) throws ChecksumException {
//////    int codewords = dataCodewords + ecCodewords;
//////
//////    // in EVEN or ODD mode only half the codewords
//////    int divisor = mode == ALL ? 1 : 2;
//////
//////    // First read into an array of ints
//////    int[] codewordsInts = new int[codewords / divisor];
//////    for (int i = 0; i < codewords; i++) {
//////      if ((mode == ALL) || (i % 2 == (mode - 1))) {
//////        codewordsInts[i / divisor] = codewordBytes[i + start] & 0xFF;
//////      }
//////    }
//////    try {
//////      rsDecoder.decode(codewordsInts, ecCodewords / divisor);
//////    } catch (ReedSolomonException rse) {
//////      throw ChecksumException.getChecksumInstance();
//////    }
//////    // Copy back into array of bytes -- only need to worry about the bytes that were data
//////    // We don't care about errors in the error-correction codewords
//////    for (int i = 0; i < dataCodewords; i++) {
//////      if ((mode == ALL) || (i % 2 == (mode - 1))) {
//////        codewordBytes[i + start] = (byte) codewordsInts[i / divisor];
//////      }
//////    }
//////  }
//////
//////}
